const bcrypt = require('bcryptjs')

const jwt = require('jsonwebtoken')

const { JWT_SECRET } = require('../config/config.default')

const { tokenExpiredError, invalidToken } = require('../constant/err.type')


const { getUerInfo } = require('../service/user.service')
const {
    userFormateError,
    userAlreadyExited,
    userRegisterError,
    userDoesNotExist,
    userLoginError,
    invalidPassword,
} = require('../constant/err.type')

//username password 是否为空
const userValidator = async (ctx, next) => {
    const { username, password } = ctx.request.body
    // 合法性
    if (!username || !password) {
        console.error('用户名或密码为空', ctx.request.body)
        ctx.app.emit('error', userFormateError, ctx)
        return
    }
    // console.log('1111');
    await next()
}

//注册时候用户是否存在
const verifyUser = async (ctx, next) => {
    const { username } = ctx.request.body

    // if (await getUerInfo({ username })) {
    //   ctx.app.emit('error', userAlreadyExited, ctx)
    //   return
    // }
    try {
        const res = await getUerInfo({ username })
        console.log(res, 'middleware');
        if (res) {
            console.error('用户名已经存在', { username })
            ctx.app.emit('error', userAlreadyExited, ctx)
            return
        }
    } catch (err) {
        console.error('获取用户信息错误', err)
        ctx.app.emit('error', userRegisterError, ctx)
        return
    }

    await next()
}

//数据库password加密
const crpytPassword = async (ctx, next) => {
    const { password } = ctx.request.body
    console.log(password);
    const salt = bcrypt.genSaltSync(10)
    console.log(typeof salt);
    // hash保存的是 密文
    const hash = bcrypt.hashSync(password, salt)
    console.log(hash, 'hash');
    console.log('abc');
    ctx.request.body.password = hash
    await next()
}

//验证password username 信息是否正确
const verifyLogin = async (ctx, next) => {
    // 1. 判断用户是否存在(不存在:报错)
    const { username, password } = ctx.request.body

    try {
        const res = await getUerInfo({ username })

        if (!res) {
            console.error('用户名不存在', { username })
            ctx.app.emit('error', userDoesNotExist, ctx)
            return
        }

        // 2. 密码是否匹配(不匹配: 报错)
        if (!bcrypt.compareSync(password, res.password)) {
            ctx.app.emit('error', invalidPassword, ctx)
            return
        }
    } catch (err) {
        console.error(err)
        return ctx.app.emit('error', userLoginError, ctx)
    }

    await next()
}


const auth = async (ctx, next) => {
    const { authorization } = ctx.request.header
    const token = authorization.replace('Bearer ', '')
    console.log(token)

    try {
        // user中包含了payload的信息(id, username, is_admin)
        const user = jwt.verify(token, JWT_SECRET)
        ctx.state.user = user
    } catch (err) {
        switch (err.name) {
            case 'TokenExpiredError':
                console.error('token已过期', err)
                return ctx.app.emit('error', tokenExpiredError, ctx)
            case 'JsonWebTokenError':
                console.error('无效的token', err)
                return ctx.app.emit('error', invalidToken, ctx)
        }
    }

    await next()
}


module.exports = {
    userValidator,
    verifyUser,
    crpytPassword,
    verifyLogin,
    auth,
}